package com.health.security;

import com.alibaba.dubbo.config.annotation.Reference;
import com.health.pojo.Permission;
import com.health.pojo.Role;
import com.health.pojo.User;
import com.health.service.UserService;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class UserSecurity implements UserDetailsService {

    @Reference
    private UserService userService;

    /**
     * 加载用户，及其角色，权限信息
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据用户名查询用户详细信息
        User user = userService.findDetail(username);

        //查询到，则将用户的详细信息(用户,角色,权限)交给Security管理
        if (user != null) {
            //用户角色，权限信息集合
            List<GrantedAuthority> authorityList = new ArrayList<>();

            //角色
            Role role = user.getRole();
            if (role != null) {
                //通过角色的关键词，构建Security权限对象，并存储到集合中
                authorityList.add(new SimpleGrantedAuthority(role.getKeyword()));

                //权限
                List<Permission> permissions = role.getPermissions();
                if (permissions != null && permissions.size() > 0) {
                    for (Permission permission : permissions) {
                        //通过权限的关键词，构建Security权限对象，并存储到集合中
                        authorityList.add(new SimpleGrantedAuthority(permission.getKeyword()));
                    }
                }
            }

            //返回登陆用户的信息给security，会保存到session
            return new org.springframework.security.core.userdetails.User(username,  user.getPassword(), authorityList);
        }
        //未查询到，直接返回null
        return null;
    }
}